Desafio_04

Author

Amanda Cedro - 253507 Elisa Amorim da Costa - 277145 Iuri Santos Oliveira - 194610 Pedro Galhardo Barbosa - 277218

Desafio 04:

#baixando todos os pacotes necessários para a realização desse código.
#| message: false
#| warning: false

library(readr)
library(dplyr)

Attaching package: 'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
library(lubridate)

Attaching package: 'lubridate'
The following objects are masked from 'package:base':

    date, intersect, setdiff, union
library(leaflet)

Parte 1:

Crie uma função que:

  1. Receba um valor de TAIL_NUMBER (por exemplo, N431WN);

  2. Produza uma tabela (tidy) com todos os trajetos realizados pela aeronave (ordenadas por data e hora, contendo todas as colunas do arquivo flights.csv.zip);

  3. Produza um mapa que apresente todo o trajeto voado pela aeronave ao longo de todo o ano; o trajeto deve ser apresentado de maneira linear no tempo (i.e., segue a sequência do tempo, como no exemplo hipotético dado acima);

  4. O mapa deve ser decorado com estatísticas do seu interesse (por exemplo, velocidade média do vôo como espessura da linha que conecta os aeroportos envolvidos no trajeto);

Parte 2:

  1. Seu código deve ser bem comentado;

  2. Os nomes das variáveis devem ser esclarecedores (por exemplo, x é um nome ruim);

  3. Seu código será avaliado por 5 de seus colegas;

  4. A parte de avaliação (descrita em c.) acontecerá na semana de 23 a 27 de setembro (com entrega obrigatória no dia 27);

Observações:

  1. A função terá o argumento tail_number e arquivo;

  2. O argumento tail_number será o código identificador do avião de interesse (por ex., N431WN);

  3. O argumento arquivo será o nome do arquivo com caminho completo (por ex., file.path(“dados”, “flights.csv.zip”));

  4. A função se chamará analisa_aeronave;

  5. O arquivo deve ser lido por partes;

  6. O mapa deve utilizar as coordenadas exatas dos aeroportos envolvidos (presentes no arquivo airports);

  7. A função deve retornar uma lista (nomeada) com dois valores: a tabela utilizada para o gráfico e o gráfico propriamente dito;

  8. O Jupyter não será suficiente para a realização da tarefa; utilize o RStudio; o laboratório continuará disponível nos horários da aula;

  9. O código deverá ser submetido via Moodle até o dia 23 de setembro, às 10 da manhã (em área exclusiva a ser disponibilizada oportunamente).

Código:

#Criando a função para a realização do código
analisa_aeronave <- function(tail_number, arquivo) {
  
  # Lendo o arquivo airports 
  airports <- read_csv(unz(arquivo, "airports.csv"))
  
  # Criando uma lista para colocar os dados filtrados
  flights_filtrados <- list()
  
  # Criando uma função chamada callback
  callback <- function(x, pos) {
    # Filtra os voos da aeronave escolhida
    x %>%
      filter(TAIL_NUMBER == tail_number) %>%
      collect() -> df
    flights_filtrados[[length(flights_filtrados) + 1]] <<- df
  }
  # Lendo flights em partes de 1e5 linhas
  read_csv_chunked(
    file = unz(arquivo, "flights.csv"),
    callback = SideEffectChunkCallback$new(callback),
    chunk_size = 1e5,
    progress = FALSE
  )
  
  # Combinando todas as partes
  flights <- bind_rows(flights_filtrados)
  
  # Filtrando e criando a tabela de voos
  trajeto_filtrado <- flights %>%
    mutate(
      DEPARTURE_TIME = as.numeric(DEPARTURE_TIME),
      # Criando variável de data a partir de ano/mês/dia
      DATA = make_date(YEAR, MONTH, DAY),
      # Data formatada no padrão brasileiro DD/MM/YYYY
      DATA_FORMATADA = format(DATA, "%d/%m/%Y"),
      # Dia da semana do voo (segunda, terça, etc.)
      DIA_SEMANA = wday(DATA, label = TRUE, abbr = FALSE, week_start = 1),
      # Hora formatada (HH:MM) a partir do DEPARTURE_TIME
      HORA = ifelse(!is.na(DEPARTURE_TIME),
                    sprintf("%02d:%02d", DEPARTURE_TIME %/% 100, DEPARTURE_TIME %% 100),
                    NA)
    ) %>%
    arrange(DATA, DEPARTURE_TIME)  # ordena no tempo
  
  # Adicionando coordenadas de origem/destino com base nas coordenadas exatas
  trajeto_coord <- trajeto_filtrado %>%
    left_join(airports %>% 
                select(IATA_CODE, ORIGIN_LAT = LATITUDE, ORIGIN_LON = LONGITUDE),
              by = c("ORIGIN_AIRPORT" = "IATA_CODE")) %>%
    left_join(airports %>% 
                select(IATA_CODE, DEST_LAT = LATITUDE, DEST_LON = LONGITUDE),
              by = c("DESTINATION_AIRPORT" = "IATA_CODE")) %>%
    mutate(
      # Velocidade média do voo (milhas por hora)
      # DISTANCE (em milhas) / tempo de voo em horas
      velocidade_media = DISTANCE / (AIR_TIME/60)
    ) %>%
    # Filtrando os na's
    filter(!is.na(ORIGIN_LAT), !is.na(ORIGIN_LON),
           !is.na(DEST_LAT), !is.na(DEST_LON),
           !is.na(DISTANCE), !is.na(AIR_TIME), AIR_TIME > 0)
  
    # Calculando dia da semana mais frequente de saída de cada aeroporto
  dia_frequente <- trajeto_coord %>%
    group_by(ORIGIN_AIRPORT, DIA_SEMANA) %>%
    summarise(voos = n(), .groups = "drop") %>%
    group_by(ORIGIN_AIRPORT) %>%
    slice_max(voos, n = 1) %>%
    select(ORIGIN_AIRPORT, dia_frequente = DIA_SEMANA)
  
  # Criando paleta de cores para os dias da semana
  paleta_cores <- colorFactor(
    palette = c("#E57373", "#64B5F6", "#81C784", "#BA68C8", 
                "#FFB74D", "#FFF176", "#A1887F"),
    domain = trajeto_coord$DIA_SEMANA
  )
  
  # Criando mapa base
  mapa_base <- leaflet() %>%
    addTiles()
  
  # Adicionando linhas de voo no mapa base
  for (i in 1:nrow(trajeto_coord)) {
    mapa_base <- mapa_base %>%
      addPolylines(
        lng = c(trajeto_coord$ORIGIN_LON[i], trajeto_coord$DEST_LON[i]),
        lat = c(trajeto_coord$ORIGIN_LAT[i], trajeto_coord$DEST_LAT[i]),
        # Espessura da linha cresce com a distância do voo 
        weight = pmax(1, trajeto_coord$DISTANCE[i] / 500),
        # Cor da linha representa o dia da semana 
        color = paleta_cores(trajeto_coord$DIA_SEMANA[i]),
        opacity = 0.8,
        popup = paste0("De ", trajeto_coord$ORIGIN_AIRPORT[i], 
                       " para ", trajeto_coord$DESTINATION_AIRPORT[i],
                       "<br><b>Data:</b> ", trajeto_coord$DATA_FORMATADA[i],
                       " (", trajeto_coord$DIA_SEMANA[i], ")",
                       "<br><b>Distância:</b> ", trajeto_coord$DISTANCE[i], " milhas",
                       "<br><b>Velocidade média:</b> ", round(trajeto_coord$velocidade_media[i], 1), " mph")
      )
  }
  
   # Criando tabela selecionando as colunas de interesse e removendo a repetição de aeroportos
  aeroportos_unicos <- trajeto_coord %>%
    select(ORIGIN_AIRPORT, ORIGIN_LAT, ORIGIN_LON) %>%
    distinct() %>%
    left_join(dia_frequente, by = "ORIGIN_AIRPORT")
  
  
  # Adicionando marcadores neutros nos aeroportos
  mapa_base <- mapa_base %>%
    addCircleMarkers(
      lng = aeroportos_unicos$ORIGIN_LON,
      lat = aeroportos_unicos$ORIGIN_LAT,
      radius = 3,         
      color = "black",
      fillColor = "white",
      fillOpacity = 0.5,
      stroke = TRUE,
      weight = 1,
      popup = paste0("Aeroporto: ", aeroportos_unicos$ORIGIN_AIRPORT,
                     "<br>Maior frequência: ", aeroportos_unicos$dia_frequente)
    )
  
  # Adicionando legenda ao mapa com os dias da semana
  mapa_final <- mapa_base %>%
    addLegend(
      "bottomright",
      pal = paleta_cores,
      values = trajeto_coord$DIA_SEMANA,
      title = "Dia da Semana",
      opacity = 1
    )
  
  # Retornando uma variável contendo tabela + mapa
  return(list(
    tabela = trajeto_coord,
    mapa = mapa_final
  ))
}

# Input (basta escolher a aeronave a ser analisada(TAIL_NUMBER) e mudar o caminho para o dado, caso necessário)
resultado <- analisa_aeronave("N431WN", file.path("dados", "flights.csv.zip"))
Rows: 322 Columns: 7
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (5): IATA_CODE, AIRPORT, CITY, STATE, COUNTRY
dbl (2): LATITUDE, LONGITUDE

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

── Column specification ────────────────────────────────────────────────────────
cols(
  .default = col_double(),
  AIRLINE = col_character(),
  TAIL_NUMBER = col_character(),
  ORIGIN_AIRPORT = col_character(),
  DESTINATION_AIRPORT = col_character(),
  SCHEDULED_DEPARTURE = col_character(),
  DEPARTURE_TIME = col_character(),
  WHEELS_OFF = col_character(),
  WHEELS_ON = col_character(),
  SCHEDULED_ARRIVAL = col_character(),
  ARRIVAL_TIME = col_character(),
  CANCELLATION_REASON = col_character()
)
ℹ Use `spec()` for the full column specifications.
head(resultado$tabela)
# A tibble: 6 × 40
   YEAR MONTH   DAY DAY_OF_WEEK AIRLINE FLIGHT_NUMBER TAIL_NUMBER ORIGIN_AIRPORT
  <dbl> <dbl> <dbl>       <dbl> <chr>           <dbl> <chr>       <chr>         
1  2015     1     1           4 WN               1762 N431WN      DCA           
2  2015     1     1           4 WN               3564 N431WN      HOU           
3  2015     1     1           4 WN               3564 N431WN      BOS           
4  2015     1     1           4 WN               3564 N431WN      BWI           
5  2015     1     2           5 WN               1793 N431WN      MCI           
6  2015     1     2           5 WN               1793 N431WN      LAX           
# ℹ 32 more variables: DESTINATION_AIRPORT <chr>, SCHEDULED_DEPARTURE <chr>,
#   DEPARTURE_TIME <dbl>, DEPARTURE_DELAY <dbl>, TAXI_OUT <dbl>,
#   WHEELS_OFF <chr>, SCHEDULED_TIME <dbl>, ELAPSED_TIME <dbl>, AIR_TIME <dbl>,
#   DISTANCE <dbl>, WHEELS_ON <chr>, TAXI_IN <dbl>, SCHEDULED_ARRIVAL <chr>,
#   ARRIVAL_TIME <chr>, ARRIVAL_DELAY <dbl>, DIVERTED <dbl>, CANCELLED <dbl>,
#   CANCELLATION_REASON <chr>, AIR_SYSTEM_DELAY <dbl>, SECURITY_DELAY <dbl>,
#   AIRLINE_DELAY <dbl>, LATE_AIRCRAFT_DELAY <dbl>, WEATHER_DELAY <dbl>, …
resultado$mapa